package net.xdclass.aspect;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import net.xdclass.annotation.ShareCodeCheck;
import net.xdclass.enums.BizCodeEnum;
import net.xdclass.exception.BizException;
import net.xdclass.util.JwtUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * @author 姜阿木
 * @date 2025/7/23 9:52
 */
@Aspect
@Component
@Slf4j
public class ShareCodeAspect {
    // 新建一个threadLocal 存储shareId
    private static final ThreadLocal<Long> shareIdThreadLocal = new ThreadLocal<>();

    /**
     * 设置shareId
     * @param
     */
    public static void setShareId(Long shareId) {
        shareIdThreadLocal.set(shareId);
    }

    /**
     * 获取shareId
     * @return
     */
    public static Long getShareId() {
        return shareIdThreadLocal.get();
    }

    /**
     * 定义 @Pointcut注解表达式
     * 方式一：@annotation:当执行方法上拥有指定的注解时生效
     * 方式二：execution:当执行方法满足指定的表达式时生效
     */

    @Pointcut("@annotation(shareCodeCheck)")
    public void pointCutShareCodeCheck(ShareCodeCheck shareCodeCheck) {
    }


    /**
     * 配置环绕通知，围绕方法执行
     */
    @Around("pointCutShareCodeCheck(shareCodeCheck)")
    public Object around(ProceedingJoinPoint joinPoint, ShareCodeCheck shareCodeCheck) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getRequest();

        String shareToken = request.getHeader("share-token");
        if (StringUtils.isBlank(shareToken)){
            throw new BizException(BizCodeEnum.SHARE_CODE_ILLEGAL);
        }
        Claims claims = JwtUtil.checkShareJWT(shareToken);
        if (claims == null){
            log.error("share-token解析失败");
            throw new BizException(BizCodeEnum.SHARE_CODE_ILLEGAL);
        }
        Long shareId = Long.valueOf(claims.get(JwtUtil.CLAIM_SHARE_KEY) + "");
        setShareId(shareId);
        log.info("环绕通知执行前");
        Object result = joinPoint.proceed();
        log.info("环绕通知执行后");
        return result;
    }

}
